<?php
/***********************************************************************
 * @package     IvanEngine
 * @subpackage  Framework
 * @author      Ivan <ivanzx@msn.com>
 * @created     2010-05-23
 ***********************************************************************/
if(defined("IVANENGINE_FRAMEWORK_CONTEXT"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_FRAMEWORK_CONTEXT", true);

require_once (dirname(__FILE__).'/Common.php');
require_once (dirname(__FILE__).'/MVC/Controller.php');
require_once (dirname(__FILE__).'/User.php');
require_once (M_CORE_PATH.'Request.php');
require_once (M_CORE_PATH.'Response.php');
require_once (M_CORE_PATH.'IO/SessionStorage.php');

class CContext extends CSingleton 
{
    static protected $m_this    = null;
    protected
        $m_request      = null,
        $m_response     = null,
        $m_routing      = null,
        $m_i18n         = null,
        $m_storage      = null,
        $m_user         = null,
        $m_controller   = null,
        $m_engine       = null;
        
	public function __construct()
	{
		parent::__construct();
	}

	public function __destruct()
	{
        unset($this->m_request);
        unset($this->m_response);
        unset($this->m_routing);
        unset($this->m_i18n);
        unset($this->m_user);
        unset($this->m_storage);
        unset($this->m_controller);
        unset($this->m_engine);
		parent::__destruct();
	}
    
    static public function Get()
    {
        if( self::$m_this == null )
        {
            parent::StartSingleton();
            self::$m_this = new CContext();
            parent::EndSingleton();
        }
        return self::$m_this;
    }
    
    public function Initialize(CEngine & $engine)
    {
        $this->m_engine     = $engine;
        $this->m_request    = CRequest::Get();
        $this->m_response   = CResponse::Get();
        $this->m_storage    = CSessionStorage::Get();
        require(CConfig::Option(CConfig::OT_PluginPath).M_DS.'User.php');
        $this->m_user       = new CMyUser();
        $this->m_controller = new CController();
        $this->m_i18n       = CI18NManager::Get();
        
        $this->m_request->Initialize();
        $this->m_response->Initialize();
        
        // load routing object
        $routingClassNode   = CConfig::Option(CConfig::OT_RoutingClass);
        if( $routingClassNode == null ){
            throw new CExceptionInvalidArgument(
                'can not find out routing class option in CConfig::Option.');
        }
        if( !$routingClassNode instanceof CXmlNode ){
            throw new CExceptionInvalidArgument(
                'routing class parameter is error, you need set \'file\' attribute.');
        }
        $classFile  = $routingClassNode->GetAttribute('file');
        if( !CFileHelper::IsAbsolutePath($classFile) ){
            $classFile  = CConfig::Option(CConfig::OT_ProjPath).M_DS.$classFile;
            $classFile  = CFileHelper::CorrectPath($classFile);
        }
        if( !CFileHelper::IsReadable($classFile) ){
            throw new CExceptionInvalidArgument(
                'can not open the routing file:<br>'.$classFile);
        }
        require_once($classFile);
        $routingClassname  = $routingClassNode->GetContent();
        $routingClassname  = trim($routingClassname);
        if( !class_exists($routingClassname) ){
            throw new CExceptionInvalidArgument(
                'can not find out routing class in the file:<br>'.$routingClassNode);
        }
        
        $this->m_routing    = new $routingClassname();
        CUrlHelper::SetRouting($this->m_routing);
    }
    
    public function & Dispatch()
    {
        $pluginName = $this->m_request->GetParameter('plugin');
        $actionName = $this->m_request->GetParameter('action');
        
        $pluginName = ucfirst($pluginName);
        $actionName = ucfirst($actionName);

        if( !empty($pluginName) && !$this->m_request->IsXmlHttpRequest() &&
            $pluginName != CConfig::Option(CConfig::OT_SecurePlugin) &&
            $actionName != CConfig::Option(CConfig::OT_SecureAction))
        {
            throw new CException404Error('You can not direct access the page.');
        }
        
        $this->m_controller->Forward($pluginName, $actionName);
    }
    
    public function & GetEngine()
    {
        return $this->m_engine;
    }
    
    public function & GetController()
    {
        return $this->m_controller;
    }
    
    public function & GetRequest()
    {
        return $this->m_request;
    }
    
    public function & GetResponse()
    {
        return $this->m_response;
    }
    
    public function & GetRouting()
    {
        return $this->m_routing;
    }
    
    public function & GetStorage()
    {
        return $this->m_storage;
    }
    
    public function & GetUser()
    {
        return $this->m_user;
    }
    
    public function & GetI18N()
    {
        return $this->m_i18n;
    }
}

?>